<script setup lang="ts">
import { ref, computed } from 'vue'
import {
  getAllTradeMarkService,
  getSpuImageService,
  getAttrSaleService,
  getAllSaleAttrService,
  addSpuService,
  updateSpuService
} from '@/apis/product/spu'
import type {
  SpuData,
  TradeMark,
  TradeMarkResponseData,
  SpuImage,
  SpuImageResponseData,
  SaleAttr,
  SaleAttrValue,
  SaleAttrResponseData,
  AllSaleAttr,
  AllSaleAttrResponseData
} from '@/apis/product/spu/type'
import type { UploadProps } from 'element-plus'
import { useCategoryStore } from '@/stores'

const categoryStore = useCategoryStore()
// 取消
const model = defineModel()
const onCancel = () => {
  model.value = 1
}
// 切换
const spuParams = ref<SpuData>({
  id: '',
  spuName: '',
  description: '',
  category3Id: '',
  tmId: '',
  spuSaleAttrList: [],
  spuImageList: []
})
const trademark = ref<TradeMark[]>([])
const spuImage = ref<SpuImage[]>([])
const saleAttr = ref<SaleAttr[]>([])
const allSaleAttr = ref<AllSaleAttr[]>([])
const initSpu = async (row: SpuData) => {
  // 编辑
  if (row.id) {
    spuParams.value = row
    // 获取spu图片
    const res2: SpuImageResponseData = await getSpuImageService(row.id)
    spuImage.value = res2.data.map((item) => ({
      name: item.imgName,
      url: item.imgUrl
    }))
    // 获取spu销售属性
    const res3: SaleAttrResponseData = await getAttrSaleService(row.id)
    saleAttr.value = res3.data
  } else {
    spuImage.value = []
    saleAttr.value = []
    saleAttrIdName.value = ''
    spuParams.value = {
      id: '',
      spuName: '',
      description: '',
      category3Id: categoryStore.option3,
      tmId: '',
      spuSaleAttrList: [],
      spuImageList: []
    }
  }
  // 获取所有品牌
  const res1: TradeMarkResponseData = await getAllTradeMarkService()
  trademark.value = res1.data
  // 获取全部销售属性
  const res4: AllSaleAttrResponseData = await getAllSaleAttrService()
  allSaleAttr.value = res4.data
}

// 照片墙
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
// 预览照片
const onPreview: UploadProps['onPreview'] = (file) => {
  dialogImageUrl.value = file.url!
  dialogVisible.value = true
}
// 删除照片
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
  if (
    file.type !== 'image/jpeg' &&
    file.type !== 'image/png' &&
    file.type !== 'image/gif'
  ) {
    ElMessage.error('上传图片只能是 JPG/PNG/GIF 格式!')
    return false
  }
  if (file.size / 1024 / 1024 > 4) {
    ElMessage.error('上传图片大小不能超过 4MB!')
    return false
  }
  return true
}
// 计算未选择属性
const unSelectSaleAttr = computed(() => {
  return allSaleAttr.value.filter((item) => {
    return saleAttr.value.every((item1) => item.name !== item1.saleAttrName)
  })
})
// 销售属性id和name
const saleAttrIdName = ref<string>('')
// 添加销售属性
const addSaleAttr = () => {
  const [baseSaleAttrId, saleAttrName] = saleAttrIdName.value.split(':')
  const newSaleAttr: SaleAttr = {
    baseSaleAttrId,
    saleAttrName,
    spuSaleAttrValueList: []
  }
  saleAttr.value.push(newSaleAttr)
  saleAttrIdName.value = ''
}

// tag标签添加
const toAdd = (row: SaleAttr) => {
  row.flag = true
}
// 查看
const toLook = (row: SaleAttr) => {
  const { baseSaleAttrId, saleAttrValueName } = row
  const newSaleAttrValue: SaleAttrValue = {
    baseSaleAttrId,
    saleAttrValueName: saleAttrValueName!
  }
  // 不能为空
  if (!saleAttrValueName) return ElMessage.error('请输入属性值')
  // 不能重复
  const isRepeat = row.spuSaleAttrValueList.some(
    (item) => item.saleAttrValueName === saleAttrValueName
  )
  if (isRepeat) return ElMessage.error('属性值不能重复')
  row.spuSaleAttrValueList.push(newSaleAttrValue)
  row.saleAttrValueName = ''
  row.flag = false
}
// 父子通信
const emits = defineEmits(['changeScene'])

// 添加/修改
const onSave = async () => {
  // 照片墙
  spuParams.value.spuImageList = spuImage.value.map((item: any) => ({
    imgUrl: item.response?.data || item.url,
    imgName: item.name
  }))
  // 销售属性
  spuParams.value.spuSaleAttrList = saleAttr.value

  if (spuParams.value.id) {
    await updateSpuService(spuParams.value)
  } else {
    await addSpuService(spuParams.value)
    console.log(spuParams.value)
  }

  ElNotification.success({
    title: '提示',
    message: spuParams.value.id ? '修改成功' : '添加成功'
  })
  emits('changeScene', spuParams.value.id ? 'update' : 'add')
  model.value = 1
}

defineExpose({
  initSpu
})
</script>

<template>
  <el-form label-width="100px">
    <el-form-item label="SPU名称">
      <el-input
        placeholder="请输入SPU名称"
        v-model="spuParams.spuName"
      ></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select
        placeholder="请选择SPU品牌"
        v-model="spuParams.tmId"
        style="width: 200px"
      >
        <el-option
          v-for="item in trademark"
          :key="item.id"
          :label="item.tmName"
          :value="item.id"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述">
      <el-input
        type="textarea"
        placeholder="请选择SPU描述"
        v-model="spuParams.description"
      ></el-input>
    </el-form-item>
    <el-form-item label="SPU照片">
      <el-upload
        v-model:file-list="spuImage"
        action="/api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="onPreview"
        :before-upload="beforeUpload"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img
          w-full
          :src="dialogImageUrl"
          alt="Preview Image"
          style="width: 100%; height: 100%"
        />
      </el-dialog>
    </el-form-item>
    <el-form-item label="SPU销售属性">
      <el-select
        v-model="saleAttrIdName"
        :placeholder="
          unSelectSaleAttr.length > 0
            ? `还有${unSelectSaleAttr.length}未选择`
            : '无销售属性可选择'
        "
        style="width: 200px"
      >
        <el-option
          v-for="item in unSelectSaleAttr"
          :key="item.id"
          :label="item.name"
          :value="`${item.id}:${item.name}`"
        ></el-option>
      </el-select>
      <el-button
        @click="addSaleAttr"
        :disabled="!saleAttrIdName"
        type="primary"
        icon="Plus"
        style="margin-left: 20px"
        >添加销售属性</el-button
      >
    </el-form-item>
    <!-- 销售属性表格 -->
    <el-form-item>
      <el-table border :data="saleAttr">
        <el-table-column
          label="序号"
          type="index"
          align="center"
          width="80px"
        ></el-table-column>
        <el-table-column
          label="属性名"
          width="120px"
          prop="saleAttrName"
        ></el-table-column>
        <el-table-column label="属性值">
          <template #default="{ row }">
            <el-tag
              v-for="(item, index) in row.spuSaleAttrValueList"
              :key="item.id"
              closable
              @close="row.spuSaleAttrValueList.splice(index, 1)"
              style="margin: 5px 10px"
              >{{ item.saleAttrValueName }}</el-tag
            >
            <el-button
              type="primary"
              size="small"
              icon="Plus"
              @click="toAdd(row)"
              v-show="!row.flag"
            ></el-button>
            <el-input
              v-model="row.saleAttrValueName"
              size="small"
              placeholder="请输入属性值"
              style="width: 100px"
              @blur="toLook(row)"
              v-show="row.flag"
            ></el-input>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120px">
          <template #default="{ $index }">
            <el-button
              icon="Delete"
              type="danger"
              circle
              @click="saleAttr.splice($index, 1)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <!-- 保存、取消 -->
    <el-form-item>
      <el-button :disabled="!saleAttr.length" type="primary" @click="onSave"
        >保存</el-button
      >
      <el-button type="primary" @click="onCancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>
